package assets {
	import flash.display.Loader;
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	
	/**
	 * @author Charlie MacIsaac
	 */
	
	public class AssetLoader {
		// PROPERTIES =============================================================================
		private var _asset : Asset;
		private var _completeCallBack : Function;
		private var _domain : ApplicationDomain;
		
		private var _dataLoader : URLLoader;
		private var _imageLoader : Loader;
		
		private var _percentageLoaded : Number;
		
		// GETTERS + SETTERS ======================================================================
		internal function get percentLoaded() : Number {
			return _percentageLoaded;
		}
		
		// CONSTRUCTOR =============================================================================
		public function AssetLoader(asset : Asset, completeCallBack : Function, domain : ApplicationDomain = null) {
			_percentageLoaded = 0;
			_asset = asset;
			_asset.loader = this;
			_completeCallBack = completeCallBack;
			_domain = domain ? domain : ApplicationDomain.currentDomain;
		}
		
		internal function load() : void {
			if (_asset.isData)	loadAsData();
			else				loadAsImage();
		}
		
		// PUBLIC =================================================================================
		private function loadAsImage() : void {
			_imageLoader = new Loader();
			_imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete , false, 0, true);
			_imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler, false, 0, true);
			_imageLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadError, false, 0, true);
			_imageLoader.load(_asset.url, new LoaderContext(false, _domain));
		}
		
		private function loadAsData() : void {
			_dataLoader = new URLLoader();
			_dataLoader.addEventListener(Event.COMPLETE, loadComplete, false, 0, true);
			_dataLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler, false, 0, true);
			_dataLoader.addEventListener(IOErrorEvent.IO_ERROR, loadError, false, 0, true);
			_dataLoader.load(_asset.url);
		}
		
		private function loadError(e : IOError) : void {
			throw new Error("[AssetLoader.loadError] |ERROR| " + e.message);
		}
		
		private function loadComplete(e : Event) : void {
			if (_imageLoader) {
				_imageLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loadComplete);
				_imageLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
				_imageLoader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, loadError);
				_asset.data = _imageLoader.content;
			} else if (_dataLoader) {
				_dataLoader.removeEventListener(Event.COMPLETE, loadComplete);
				_dataLoader.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
				_dataLoader.removeEventListener(IOErrorEvent.IO_ERROR, loadError);
				_asset.data = _dataLoader.data;
			}
			if (_completeCallBack != null) _completeCallBack();
		}
		
		private function progressHandler(e : ProgressEvent) : void {
			_percentageLoaded = (e.bytesLoaded / e.bytesTotal);
		}
	}
}